package com.xieyong.mywebsite.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import com.xieyong.mywebsite.exception.MyCustomizeException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Service
public class FileService {

    @Value("${app.upload-dir}")
    private String  uploadDir;

    @Value("${app.base-url}:${server.port}")
    private String  baseUrl;

//    public void downLoad(HttpServletResponse response, String fileName) throws IOException {
//        String filePath = System.getProperty("user.dir") + "/" + uploadDir + "/" + fileName;
//        System.out.println(filePath);
//        boolean exist = FileUtil.exist(filePath);
//        if (!exist) {
//            throw new MyCustomizeException("文件不存在");
//        }
////        读取文件的字节流
//        byte[] bytes = FileUtil.readBytes(filePath);
//        response.addHeader("Content-Disposition", "inline;filename=" + fileName);
//        response.setContentType("application/octet-stream");
//        ServletOutputStream os = response.getOutputStream();
//        os.write(bytes);
//        os.flush();
//        os.close();
//    }

    public void downLoad(HttpServletResponse response, String fileName) throws IOException {
        String filePath = System.getProperty("user.dir") + uploadDir + fileName;

        if (!FileUtil.exist(filePath)) {
            throw new MyCustomizeException("文件不存在");
        }

        // 1. 获取文件扩展名
        String extension = FileUtil.extName(fileName).toLowerCase();

        // 2. 根据文件类型设置不同的 Content-Type
        String contentType = getContentType(extension);
        response.setContentType(contentType);

        // 3. 设置预览模式 (inline) 而不是下载模式 (attachment)
        String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
        response.setHeader("Content-Disposition", "inline; filename=\"" + encodedFileName + "\"");

        // 4. 添加缓存头，优化预览体验
        response.setHeader("Cache-Control", "max-age=3600"); // 缓存1小时

        // 5. 读取并传输文件
        try (ServletOutputStream os = response.getOutputStream();
             FileInputStream fis = new FileInputStream(filePath)) {
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.flush();
        }
    }

    // 获取文件对应的 MIME 类型
    private String getContentType(String extension) {
        return switch (extension) {
            case "pdf" -> "application/pdf";
            case "jpg", "jpeg" -> "image/jpeg";
            case "png" -> "image/png";
            case "gif" -> "image/gif";
            case "txt" -> "text/plain";
            case "html", "htm" -> "text/html";
            case "mp4" -> "video/mp4";
            case "mp3" -> "audio/mpeg";
            default -> "application/octet-stream"; // 默认二进制流
        };
    }

    public String upload(MultipartFile file) throws IOException {
//        找到文件夹的位置
        String filePath = System.getProperty("user.dir") + uploadDir;
        if(!FileUtil.isDirectory(filePath)){
            FileUtil.mkdir(filePath);
        }
//        获取文件名称
//        String filename = System.currentTimeMillis() + "_" + file.getOriginalFilename();
//        添加uuid防止文件名称重复
        String filename = UUID.randomUUID().toString() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        FileUtil.writeBytes(file.getBytes(), filePath + filename);
        return baseUrl + uploadDir + "download/" + filename;
    }

    //        更新数据前删除旧的头像
    public void removeFile(String oldPath) {
//        所有文件路由都是形如  http://localhost:9999/files/download/1752420634967_2485605602495572.jpg
//        的路由，所以以‘/’分隔字符串，然后找到文件，并删除就行
        if(StrUtil.isBlank(oldPath)){
            return;
        }
        String[] urlSplit = oldPath.split("/");
        String fileName = urlSplit[urlSplit.length - 1];
        String filePath = System.getProperty("user.dir") + uploadDir + fileName;
        System.out.println(filePath);
        try{
            if (FileUtil.exist(filePath)) {
                Path path = Paths.get(filePath);
                Files.delete(path);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

//    该方法为wangeditor固定的方法，返回值以此为准
    public Map<String, Object> wangUpload(MultipartFile file) {
//        String fileName = System.currentTimeMillis() + "-" + file.getOriginalFilename();
        String filename = UUID.randomUUID().toString() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        String filePath = System.getProperty("user.dir") + uploadDir + filename;
        try{
            FileUtil.writeBytes(file.getBytes(), filePath);
            System.out.println(filename + "----上传成功");
            Thread.sleep(1);
        } catch (Exception e) {
            System.out.println(filename + "----文件上传失败");
            throw new MyCustomizeException("文件上传失败");
        }
        String http = baseUrl + uploadDir + "download/";
        Map<String, Object> resmap = new HashMap<>();
        resmap.put("errno", 0);
        resmap.put("data", CollUtil.newArrayList(Dict.create().set("url", http + filename)));
        return resmap;
    }
}
